package hc.bre.clas

import hc.bre.clas.range.RangeOption
import hc.bre.cmn.IListOption
import hc.bre.cmn.ListOption
import hc.bre.cmn.RuleScriptBuilder
import hc.bre.data.encoder.EncoderItem

@groovy.transform.CompileStatic
abstract class ClasBuilder<T extends ClasRuleDefinition> extends RuleScriptBuilder<T>{
	@Override
	public void buildClassMemberClass() {
		String listOptionItf = className(IListOption.class)
		apdInnerClass("ClasOption implements ${listOptionItf}"){
			apdNlBlock(IListOption.declarationOfOption());
		}
	}

	@Override
	public void buildClassMemberVariable() {
		List<ListOption> lst = ruleDef.list;

		lst.each { ListOption it ->
			apdStaticFinalVar("ClasOption"
					,it.code
					,"new ClasOption(id:${it.id}, code:${referText(it.code)}, name:${referText(it.name)})");
		}
	}

	@Override
	public void buildClassRuleBodyCore() {
		List<RangeOption> list = (ruleDef.list as List<RangeOption>).sort { a,b-> a.otherflag - b.otherflag };

		apdNl("switch(${rangeVariable()}){")

		nested{
			RangeOption opt;
			
			for(int i = 0 ; i < list.size() - 1; i ++) {
				opt = list[i];
				apdNl("case ${opt.range} :")
						.indentInc()
						.apdNl("${result}.clas = ${referRuleClass()}.${opt.code};")
						.apdNl("break;")
						.indentDec();
			};

			opt = list[list.size()-1];
			apdNl("default :")
					.indentInc()
					.apdNl("${result}.clas = ${referRuleClass()}.${opt.code};")
					.apdNl("break;")
					.indentDec();
		}

		apdNl("};")
	}
	
	//extract it to test easily
	abstract String rangeVariable();
	
	
	@Override
	public Class buildClassRuleBodyResult_Class() {
		return ClasResult.class;
	}
}
